import { AudioUrl, PlaneCamp, PlaneEvent, PropType } from "../Constant/Constant";
import AudioManager from "../Manager/AudioManager";
import PoolManager from "../Manager/PoolManager";
import BulletControl from "./BulletControl";
import PropControl from "./PropControl";

const { ccclass, property } = cc._decorator;

/**
 * 玩家飞机逻辑控制类
 */
@ccclass
export default class PlayerControl extends cc.Component {

  playerPlanePrefab: cc.Prefab = null

  @property(cc.Prefab)
  bullet1Prefab: cc.Prefab = null

  @property
  bulletInterval: number = 0.5

  @property(cc.SpriteFrame)
  dieSpritFrame = null

  private currBuulletMethod: Function = null

  // onLoad () {}

  start() {
    this.init()
  }

  update(dt) {
  }

  onDestroy(): void {
    if (this.currBuulletMethod != null) {
      this.unschedule(this.currBuulletMethod)
    }
  }

  /**
   * 初始化飞机
   */
  public init(): void {
    this.settingDragPlane()
    this.setFireBullet(this.fireBullet1)
  }

  /**
   * 设置拖动控制飞机
   */
  private settingDragPlane(): void {
    // 监听触摸移动事件
    this.node.on(cc.Node.EventType.TOUCH_MOVE, (event: cc.Event.EventTouch) => {
      this.node.setPosition(event.getLocation())
    })
  }

  /**
   * 设置发射的子弹
   * @param fireBulletMethod 
   */
  private setFireBullet(fireBulletMethod: Function) {
    if (this.currBuulletMethod != null) {
      this.unschedule(this.currBuulletMethod)
    }
    this.schedule(fireBulletMethod, this.bulletInterval)
    this.currBuulletMethod = fireBulletMethod
  }

  /**
   * 发射子弹
   */
  private fireBullet1(): void {
    const bullet = PoolManager.instance.getNode(this.bullet1Prefab)
    bullet.getComponent(BulletControl).from = PlaneCamp.PLAYER  // 设置子弹发射源为玩家，用于碰撞检测
    bullet.parent = cc.director.getScene()
    bullet.setPosition(this.node.x, this.node.y + this.node.height / 2 + 10)
    // 播放子弹音乐
    // this.bulletAudioSource.play()
  }

  /**
   * 发射子弹
   */
  private fireBullet2(): void {
    const bulletNo1 = PoolManager.instance.getNode(this.bullet1Prefab)
    const bulletNo2 = PoolManager.instance.getNode(this.bullet1Prefab)
    bulletNo1.getComponent(BulletControl).from = PlaneCamp.PLAYER  // 设置子弹发射源为玩家，用于碰撞检测
    bulletNo1.parent = cc.director.getScene()
    bulletNo1.setPosition(this.node.x - 8, this.node.y + this.node.height / 2 + 10)

    bulletNo2.getComponent(BulletControl).from = PlaneCamp.PLAYER  // 设置子弹发射源为玩家，用于碰撞检测
    bulletNo2.parent = cc.director.getScene()
    bulletNo2.setPosition(this.node.x + 8, this.node.y + this.node.height / 2 + 10)
    // 播放子弹音乐
    // this.bulletAudioSource.play()
  }

  /**
   * 发射子弹
   */
  private fireBullet3(): void {
    const bulletNo1 = PoolManager.instance.getNode(this.bullet1Prefab)
    const bulletNo2 = PoolManager.instance.getNode(this.bullet1Prefab)
    const bulletNo3 = PoolManager.instance.getNode(this.bullet1Prefab)
    bulletNo1.getComponent(BulletControl).from = PlaneCamp.PLAYER  // 设置子弹发射源为玩家，用于碰撞检测
    bulletNo1.parent = cc.director.getScene()
    bulletNo1.setPosition(this.node.x, this.node.y + this.node.height / 2 + 10)

    bulletNo2.getComponent(BulletControl).from = PlaneCamp.PLAYER  // 设置子弹发射源为玩家，用于碰撞检测
    bulletNo2.parent = cc.director.getScene()
    bulletNo2.setPosition(this.node.x - 32, this.node.y + this.node.height / 2 - 43)

    bulletNo3.getComponent(BulletControl).from = PlaneCamp.PLAYER  // 设置子弹发射源为玩家，用于碰撞检测
    bulletNo3.parent = cc.director.getScene()
    bulletNo3.setPosition(this.node.x + 32, this.node.y + this.node.height / 2 - 43)
    // 播放子弹音乐
    // this.bulletAudioSource.play()
  }

  public die(): void {
    // 切换爆炸图片
    this.node.getComponent(cc.Sprite).spriteFrame = this.dieSpritFrame
    this.node.off(cc.Node.EventType.TOUCH_MOVE)
    // 播放爆炸音乐
    AudioManager.playEffect(AudioUrl.HERO_BLOWUP)

    // 0.5s后销毁
    this.scheduleOnce(() => {
      this.node.destroy()
      // 发送击毁事件
      const event = new cc.Event.EventCustom(PlaneEvent.DIED, true)
      this.node.dispatchEvent(event);
    }, 0.5)
  }

  /**
   * 切换子弹类型
   */
  private switchBullet(propType: PropType) {
    switch (propType) {
      case PropType.BLUE:
        this.setFireBullet(this.fireBullet2)
        console.log('PropType.BLUE')
        break;
      case PropType.RED:
        this.setFireBullet(this.fireBullet3)
        console.log('PropType.RED')
        break;
      case PropType.BOOM:
        this.setFireBullet(this.fireBullet1)
        // 发送击毁事件
        const event = new cc.Event.EventCustom(PlaneEvent.PROP_BOOM, true)
        this.node.dispatchEvent(event);
        console.log('PropType.BOOM')
        break;
    }
  }

  /**
   * 当碰撞产生的时候调用
   * @param  {Collider} other 产生碰撞的另一个碰撞组件
   * @param  {Collider} self  产生碰撞的自身的碰撞组件
   */
  onCollisionEnter(other: cc.Collider, self: cc.Collider): void {
    console.log('on player collision enter');
    console.log('other.tag', other.tag)
    // 判断碰撞对象是否为道具 道具tag=300~399
    if (other.tag >= 300 && other.tag < 400) {
      const propType = other.getComponent(PropControl).type
      this.switchBullet(propType)
      return
    }

    this.die()
  }
}
